/*
 * Vector3f.h
 *
 *      Author: Philippe Torres
 */

#ifndef __VECT3F_H_
#define __VECT3F_H_

#include <ostream>
#include <cmath>
#include <vector>


template <typename T> class Vector3f {
public:
    T x, y, z;
    Vector3f<T>():x(), y(), z() {}
    Vector3f<T>(T a, T b, T c) {x = a; y = b; z = c; }
    Vector3f<T>(const Vector3f<T>& v) { x = v.x; y = v.y; z = v.z; }

    float norm() const { return (float)sqrt(this->dot(*this)); }
    float dot(const Vector3f<T>& v) const { return x*v.x + y*v.y + z*v.z; }

    Vector3f<T>& operator=(const Vector3f<T>& v){
        if(this != &v){
            x = v.x;
            y = v.y;
            z = v.z;
        }
        return *this;
    }
    Vector3f<T> operator^(const Vector3f<T>& v) const {
        Vector3f<T> newv;
        newv.x = y * v.z - v.y * z;
        newv.y = v.x * z - x * v.z;
        newv.z = x * v.y - v.x * y;
        return newv;
    }

    Vector3f<T> operator*(float lambda) const {
        Vector3f<T> newv;
        newv.x = lambda*x;
        newv.y = lambda*y;
        newv.z = lambda*z;
        return newv;
    }

    Vector3f<T> operator+(const Vector3f<T>& v) const {
        Vector3f<T> newv;
        newv.x = x + v.x;
        newv.y = y + v.y;
        newv.z = z + v.z;
        return newv;
    }
    Vector3f<T> operator-(const Vector3f<T>& v) const {
        Vector3f<T> newv;
        newv.x = x - v.x;
        newv.y = y - v.y;
        newv.z = z - v.z;
        return newv;
    }
    Vector3f<T>& operator/=(float scalar) {
        x /= scalar;
        y /= scalar;
        z /= scalar;
        return *this;
    }

    Vector3f<T>& normalize(){
        float n = norm();
        if(n != 0) {
            x /= n;
            y /= n;
            z /= n;
        }
        return *this;
    }

    friend std::ostream& operator<<(std::ostream &o, const Vector3f<T>& v) {
        o << "[" << v.x << "," << v.y << "," << v.z << "]";
        return o;
    }

    /*friend QDebug operator<<(QDebug qdbg, const Vector3f<T>& v) {
        qdbg.nospace() << "[" << v.x << "," << v.y << "," << v.z << "]";
        return qdbg.space();
    }*/
};


#endif /* VECT3F_H_ */
